package cn.chenyumeng.blog.service.blog.impl;

import cn.chenyumeng.blog.dto.BlogDTO;
import cn.chenyumeng.blog.dto.CommentDTO;
import cn.chenyumeng.blog.entity.Blog;
import cn.chenyumeng.blog.entity.BlogTag;
import cn.chenyumeng.blog.entity.Comment;
import cn.chenyumeng.blog.mapper.BlogMapper;
import cn.chenyumeng.blog.mapper.BlogTagMapper;
import cn.chenyumeng.blog.mapper.CommentMapper;
import cn.chenyumeng.blog.service.blog.BlogPageServer;
import cn.chenyumeng.blog.util.MarkdownUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * @program: blog->BlogPageServerImpl
 * @description:
 * @author: cg
 * @create: 2020-09-19 15:53
 **/
@Service
public class BlogPageServerImpl implements BlogPageServer {

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private BlogTagMapper blogTagMapper;

    @Autowired
    private CommentMapper commentMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public BlogDTO queryById(Long id) {
        Blog blog = blogMapper.queryByIdExcludeDescription(id);
        if (blog == null) {
            return null;
        }
        BlogDTO blogDTO = new BlogDTO();
        BeanUtils.copyProperties(blog, blogDTO);
        blogDTO.setTagIds(getTagIds(blogDTO.getId()));
        return blogDTO;
    }

    @Override
    public BlogDTO getAndConvert(Long id) {
        Blog blog = blogMapper.queryByIdExcludeDescription(id);
        if (blog == null) {
            return null;
        }
        BlogDTO blogDTO = new BlogDTO();
        BeanUtils.copyProperties(blog, blogDTO);
        blogDTO.setTagIds(getTagIds(blogDTO.getId()));
        blogDTO.setContent(MarkdownUtils.markdownToHtmlExtensions(blog.getContent()));
        return blogDTO;
    }

    @Override
    public PageInfo<List<CommentDTO>> getCommentListByBlogId(Long id, Integer page, Integer size) {
        PageHelper.startPage(page, size);
        List<Comment> comments = commentMapper.queryParentCommentByBlogId(id);
        PageInfo pageInfo = new PageInfo(comments);
        List<CommentDTO> list = new ArrayList<>();
        pageInfo.getList().forEach(comment -> {
            CommentDTO dto = new CommentDTO();
            BeanUtils.copyProperties(comment, dto);
            replyComments = new ArrayList<>();
            getChildComments(dto);
            // 时间排序
            replyComments.sort(Comparator.comparing(CommentDTO::getCreateTime));
            dto.setChildCommentList(replyComments);
            list.add(dto);
        });
        pageInfo.setList(list);
        return pageInfo;
    }

    @Override
    public int addCommentByComment(CommentDTO comment) {
        Comment com = new Comment();
        BeanUtils.copyProperties(comment, com);
        com.setCreateTime(new Date());
        Blog blog = blogMapper.queryById(comment.getBlog());
        blog.setCommentCount(commentMapper.queryBlogCommentCountByBlogId(comment.getBlog()) + 1);
        blogMapper.update(blog);
        return commentMapper.insert(com);
    }

    @Override
    public CommentDTO getCommentByCommentId(Long id) {
        Comment comment = commentMapper.queryById(id);
        CommentDTO dto = new CommentDTO();
        BeanUtils.copyProperties(comment, dto);
        return dto;
    }

    private List<CommentDTO> replyComments = new ArrayList<>();

    private void getChildComments(CommentDTO commentDTO) {
        List<Comment> comments = commentMapper.queryChildCommentByParentCommentId(commentDTO.getId());
        comments.forEach(comment -> {
            CommentDTO dto = new CommentDTO();
            BeanUtils.copyProperties(comment, dto);
            replyComments.add(dto);
            getChildComments(dto);
        });
    }

    /**
     * 通过blogId查询所对应的tagIds
     *
     * @param blogId
     * @return
     */
    private List<Long> getTagIds(Long blogId) {
        List<BlogTag> blogTags = blogTagMapper.selectBlogTagsByBlogId(blogId);
        List<Long> tags = new ArrayList<>();
        blogTags.forEach(blogTag -> tags.add(blogTag.getTagId()));
        return tags;
    }

}
